﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace ttg_internal.utils
{
    /// <summary>
    /// Stores perfomance information in special formats (xml, html and txt).
    /// </summary>
    public class PerfLogger
    {
        private List<PerfElement> _tests = new List<PerfElement>();
        private Stack<PerfElement> _cur = new Stack<PerfElement>();

        /// <summary>
        /// Creates top-level record for new test and makes it current.
        /// </summary>
        /// <param name="Name">Name of the test</param>
        /// /// <param name="Description">Short description of the test</param>
        public void AddTest(string Name, string Description)
        {
            PerfRecord rec = new PerfRecord(Name, Description, null);
            _cur.Clear();
            _cur.Push(rec);
            _tests.Add(rec);
        }

        /// <summary>
        /// Adds given element to current.
        /// If there aren't current element, does nothing.
        /// </summary>
        public PerfElement AddElement(PerfElement Element)
        {
            if (_cur.Count != 0)
            {
                _cur.Peek().Childs.Add(Element);
            }
            return Element;
        }

        public PerfRecord AddRecord(string Name, string Description, string Value)
        {
            return (PerfRecord)AddElement(new PerfRecord(Name, Description, Value));
        }

        public PerfTable AddTable(string Name, string Description,
                                  string[] XLegends, string[] YLegends)
        {
            return (PerfTable)AddElement(new PerfTable(Name,Description, XLegends, YLegends));
        }

        /// <summary>
        /// Adds given record to current and makes it current.
        /// If there aren't current record, does nothing.
        /// </summary>
        public PerfElement AddElementAndOpenIt(PerfElement Element)
        {
            if (_cur.Count != 0)
            {
                _cur.Peek().Childs.Add(Element);
                _cur.Push(Element);
            }
            return Element;
        }

        public PerfRecord AddRecordAndOpenIt(string Name, string Description, string Value)
        {
            return (PerfRecord)AddElementAndOpenIt(new PerfRecord(Name, Description, Value));
        }

        public PerfTable AddTableAndOpenIt(string Name, string Description,
                                           string[] XLegends, string[] YLegends)
        {
            return (PerfTable)AddElementAndOpenIt(new PerfTable(Name, Description, XLegends, YLegends));
        }

        /// <summary>
        /// Closes current element and opens previous (if such exists).
        /// </summary>
        public void CloseElement()
        {
            if (_cur.Count != 0)
                _cur.Pop();
        }

        /// <summary>
        /// Saves all added records as xml, html and txt files.
        /// </summary>
        /// <param name="name">Name of the file (without extension)</param>
        public void Save(string name)
        {
            XmlDocument doc = new XmlDocument();
            doc.AppendChild(doc.CreateXmlDeclaration("1.0", "koi8-r", "yes"));
            XmlNode root = doc.AppendChild(doc.CreateElement("Data"));
            foreach (PerfElement el in _tests)
                el.SaveToXml(doc, root);
            doc.Save(name + ".xml");
        }
    }
}
